﻿#include "WRWorkDaemon.h"
#include "WRWorkDevice.h"
#include "WRWorkDriver.h"
#include "WRWorkModule.h"
#include "WRWorkObject.h"
#include "WRWorkDomain.h"
#include "Runtime/WRWorkConfigProvider.h"
#include "Runtime/WRWorkDriverActivator.h"
#include "Runtime/WRWorkModuleActivator.h"
#include "Runtime/WRWorkObjectActivator.h"
#include "Runtime/WRWorkDomainActivator.h"
#include "../WRSoft-Utility/Runtime/WRClass.h"
#include "../WRSoft-Utility/Runtime/WRAppContext.h"

#include <QDir>
#include <QList>
#include <QFile>
#include <QDomDocument>
#include <QCoreApplication>

//表示默认工作模块，所有单独配置的工作对象属于此模块。
class WRDefaultModule :  public WRWorkModule
{
public:
    //初始化默认工作模块。
    WRDefaultModule(const WRArray<WRWorkObject*> objects)
    {
        WRWorkModule::setObjects(objects);
    }
};

//初始化工作设备 。
void WRWorkDaemon::initDevices(const QDomElement& config)
{
    QChar driversLiteral[] = {'d','r', 'i', 'v', 'e', 'r', 's'};
    QString driverNodeName = QString::fromRawData(driversLiteral, 6);
    QString driversNodeName = QString::fromRawData(driversLiteral, 7);
    //读取工作设备配置
    QList<WRWorkDriver*> drivers;
    {
        QDomElement element = config.firstChildElement(driversNodeName);
        if (!element.isNull())
        {
            element = element.firstChildElement(driverNodeName);
            while(!element.isNull())
            {
                WRClass* _class = WRClass::select(element);
                if (_class)
                {
                    WRWorkDriverActivator* activator = _class->cast<WRWorkDriverActivator>(WRWorkDriverActivatorType);
                    if (activator)
                    {
                        WRWorkDriver* driver = activator->create(this, element);
                        if(driver)
                        {
                            drivers.append(driver);
                        }
                    }
                }
                element = element.nextSiblingElement(driverNodeName);
            }
        }
    }
    m_drivers = drivers;
    m_devices = WRWorkDeviceCollection(m_drivers);
}
//初始化工作对象。
void WRWorkDaemon::initObjects(const QDomElement& config)
{
    QChar modulesLiteral[] = {'m','o', 'd', 'u', 'l', 'e', 's'};
    QString moduleNodeName = QString::fromRawData(modulesLiteral, 6);
    QString modulesNodeName = QString::fromRawData(modulesLiteral, 7);
    QChar objectsLiteral[] = {'o','b', 'j', 'e', 'c', 't', 's'};
    QString objectNodeName = QString::fromRawData(objectsLiteral, 6);
    QString objectsNodeName = QString::fromRawData(objectsLiteral, 7);
    //读取工作模块和工作对象配置
    QList<WRWorkModule*> modules;
    {
        QDomElement element = config.firstChildElement(modulesNodeName);
        if (!element.isNull())
        {
            element = element.firstChildElement(moduleNodeName);
            while(!element.isNull())
            {
                WRClass* _class = WRClass::select(element);
                if (_class)
                {
                    WRWorkModuleActivator* activator = _class->cast<WRWorkModuleActivator>(WRWorkModuleActivatorType);
                    if (activator)
                    {
                        WRWorkModule* module = activator->create(this, element);
                        if(module)
                        {
                            modules.append(module);
                        }
                    }
                }
                element = element.nextSiblingElement(moduleNodeName);
            }
        }

        QList<WRWorkObject*> objects;
        {
            QDomElement element = config.firstChildElement(objectsNodeName);
            if (!element.isNull())
            {
                element = element.firstChildElement(objectNodeName);
                while(!element.isNull())
                {
                    WRClass* _class = WRClass::select(element);
                    if (_class)
                    {
                        WRWorkObjectActivator* activator = _class->cast<WRWorkObjectActivator>(WRWorkObjectActivatorType);
                        if (activator)
                        {
                            WRWorkObject* object = activator->create(this, element);
                            if(object)
                            {
                                objects.append(object);
                            }
                        }
                    }
                    element = element.nextSiblingElement(objectNodeName);
                }
            }
        }
        if (objects.count())
        {
            modules.append(new WRDefaultModule(WRArray<WRWorkObject*>(objects)));
        }
    }
    m_modules = modules;
    m_objects = WRWorkObjectCollection(m_modules);
}
//初始化工作域。
void WRWorkDaemon::initDomains(const QDomElement& config)
{
    QChar domainsLiteral[] = {'d','o', 'm', 'a', 'i', 'n', 's'};
    QString domainNodeName = QString::fromRawData(domainsLiteral, 6);
    QString domainsNodeName = QString::fromRawData(domainsLiteral, 7);
    //读取工作域配置
    QList<WRWorkDomain*> domains;
    {
        QDomElement element = config.firstChildElement(domainsNodeName);
        if (!element.isNull())
        {
            element = element.firstChildElement(domainNodeName);
            while(!element.isNull())
            {
                WRClass* _class = WRClass::select(element);
                if (_class)
                {
                    WRWorkDomainActivator* activator = _class->cast<WRWorkDomainActivator>(WRWorkDomainActivatorType);
                    if (activator)
                    {
                        WRWorkDomain* domain = activator->create(this, element);
                        if(domain)
                        {
                            domains.append(domain);
                        }
                    }
                }
                element = element.nextSiblingElement(domainNodeName);
            }
        }
    }
    m_domains = domains;
}

//执行相应的初始化处理。
void WRWorkDaemon::initialize(const QDomElement& config)
{
    if (!config.isNull())
    {
        //从配置加载工作设备
        initDevices(config);
        //从配置中加载工作对象
        initObjects(config);
        //从配置中加载工作域
        initDomains(config);

        //执行工作模块初始化处理
        for(WRu i = 0, l = m_modules.count(); i < l; ++i)
        {
            m_modules[i]->onInit();
        }
        //执行工作域初始化处理
        for(WRu i = 0, l = m_domains.count(); i < l; ++i)
        {
            m_domains[i]->onInit();
        }
    }
}
//执行相应的初始化处理。
void WRWorkDaemon::initialize(const QString& configFileName)
{
    QFile file(configFileName);
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        return;
    }
    QDomDocument document;
    if (!document.setContent(&file, true)) {
        file.close();
        return;
    }
    initialize(document.documentElement());
}

//初始化工作程序。
WRWorkDaemon::WRWorkDaemon()
    : m_refCnt(1)
{
    WRAppContext* appContext = WRAppContext::current();
    WRWorkConfigProvider* provider = (WRWorkConfigProvider*)appContext->getService(WRWorkConfigProviderType);
    if (provider)
    {
        initialize(provider->content());
    }
}
//执行相应的初始化处理。
WRWorkDaemon::WRWorkDaemon(const QDomElement& config)
    : m_refCnt(1)
{
    initialize(config);
}
//初始化工作程序。
WRWorkDaemon::WRWorkDaemon(const QString& configFileName)
    : m_refCnt(1)
{
    initialize(configFileName);
}

//释放当前对象所占用的相关资源。
WRWorkDaemon::~WRWorkDaemon()
{
    //清理并删除工作域
    for(WRu i = 0, l = m_domains.count(); i < l; ++i)
    {
        WRWorkDomain* entry = m_domains[i];
        entry->onFree();
    }
    for(WRu i = 0, l = m_domains.count(); i < l; ++i)
    {
        WRWorkDomain* entry = m_domains[i];
        delete entry;
    }
    //清理并删除工作模块和工作对象
    for(WRu i = 0, l = m_modules.count(); i < l; ++i)
    {
        WRWorkModule* entry = m_modules[i];
        entry->onFree();
    }
    for(WRu i = 0, l = m_modules.count(); i < l; ++i)
    {
        WRWorkModule* entry = m_modules[i];
        delete entry;
    }
    //清理并删除工作驱动和工作设备
    for(WRu i = 0, l = m_drivers.count(); i < l; ++i)
    {
        WRWorkDriver* entry = m_drivers[i];
        delete entry;
    }
}
